package com.nancal.activiti.service.process;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.google.common.collect.Lists;
import com.nancal.activiti.entity.query.BasePageQuery;
import com.nancal.common.exception.base.BaseException;
import com.nancal.common.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.model.*;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricProcessInstanceQuery;
import org.activiti.engine.history.HistoricTaskInstance;

import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.impl.persistence.entity.CommentEntityImpl;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Attachment;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.InputStream;
import java.util.*;

/**
 * 运行中的Task相关的Service
 */
@Slf4j
@Service
@Transactional
public class ProcessTaskService {

    @Autowired
    private TaskService taskService;
    @Autowired
    HistoryService historyService;
    @Autowired
    RuntimeService runtimeService;

    @Autowired
    RepositoryService repositoryService;
    @Autowired
    ProcessRuntimeService processRuntimeService;

    /**
     * 完成任务，不设置流程变量
     *
     * @param taskId
     */
    public void completeTask(String taskId) {
        taskService.complete(taskId);
    }

    /**
     * 完成任务，并设置全局流程变量
     *
     * @param taskId
     * @param variables
     */
    public void completeTask(String taskId, Map<String, Object> variables) {
        taskService.complete(taskId, variables);
    }

    /**
     * 完成任务，并设置审批意见
     *
     * @param taskId
     * @param message
     */
    public void completeTask(String taskId, String username, String message) {

        // 2.3查询当前任务后边的连线名称
        //List<String> list = findOutComeListByTaskId(taskId);

        //  2020/10/16 可能会爆找到多个实例错误
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (!task.getAssignee().equals(username)) {
            System.out.println("审批人不符合");
            return;
        }
        if (task != null && task.getAssignee().equals(username)) {
            //需要添加此句否则审批意见表中ACT_HI_COMMENT，审批人的userId是空的
            // 2020/10/16 这个设置会与设置流程发起人冲突么
            Authentication.setAuthenticatedUserId(username);
            //添加评论
            //获取该请求的申请者
            String startUserId = historyService.createHistoricProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult().getStartUserId();
            taskService.addComment(task.getId(), task.getProcessInstanceId(), username + message + "了" + startUserId + "的申请");
            //taskService.addComment(taskId, task.getProcessInstanceId(), message);
            taskService.complete(taskId);
        }
    }

    public List<String> findOutComeListByTaskId(String taskId) {

        // 5.获取当前活动完成之后连线的名称

        Object value = null;
        Process process = null;
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        //processDefinitionId 对应表ACT_RE_PROCDEF主键信息
        String processDefinitionId = runtimeService.createProcessInstanceQuery().processInstanceId(//
                taskService.createTaskQuery().taskId(taskId).singleResult().getProcessInstanceId())//
                .singleResult().getProcessDefinitionId();
        //获取bpmnModel对象
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        //获取对应key值的process
        for (Process pro : bpmnModel.getProcesses()) {
            process = pro;
        }
        //获取所有的FlowElement信息
        Collection<FlowElement> flowElements = process.getFlowElements();

        for (FlowElement flowElement : flowElements) {
            //如果是任务节点
            if (flowElement instanceof UserTask) {
                //System.out.println(task);
                UserTask userTask = (UserTask) flowElement;
                System.out.println(userTask.getId());
                System.out.println("-------------------入线信息---------------------------");
                //获取入线信息
                List<SequenceFlow> incomingFlows = userTask.getIncomingFlows();
                for (SequenceFlow sequenceFlow : incomingFlows) {
//                    if (sequenceFlow.getConditionExpression() != null) {

                    System.out.println("连线名称：" + sequenceFlow.getName() +
                            ",连线表达式：" + sequenceFlow.getConditionExpression() +
                            ",连线下一位处理人：" + sequenceFlow.getTargetRef() +
                            ",连线上一位处理人：" + sequenceFlow.getSourceRef()
                    );

//                    }
                }
                System.out.println("-------------------出线信息---------------------------");
                //获取出线信息
                List<SequenceFlow> outgoingFlows = userTask.getOutgoingFlows();
                for (SequenceFlow sequenceFlow : outgoingFlows) {
//                    if (sequenceFlow.getConditionExpression() != null) {

                    System.out.println("连线名称：" + sequenceFlow.getName() +
                            ",连线表达式：" + sequenceFlow.getConditionExpression() +
                            ",连线下一位处理人：" + sequenceFlow.getTargetRef() +
                            ",连线上一位处理人：" + sequenceFlow.getSourceRef()
                    );

//                    }
                }
            }
        }


//        return list;
        return null;
    }


    /**
     * 根据任务id查询审批意见
     */
    public List<Comment> getComment(String taskId) {
        List<Comment> comments = taskService.getTaskComments(taskId);
        return comments;
    }


    /**
     * 指派用户任务
     *
     * @param taskId
     * @param userId
     */
    public void assigneeTask(String taskId, String userId) {
        taskService.setAssignee(taskId, userId);
    }

    /**
     * 获取历史评论信息
     *
     * @param processInstanceId
     * @return
     */
    public List<Map<String, Object>> getComments(String processInstanceId) {

        //用于返回审批信息的结果集合
        List<Map<String, Object>> result = new ArrayList<>();

        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();


        //查询出来审批信息
        List<Comment> comments = taskService.getProcessInstanceComments(processInstanceId);

        for (Comment comment : comments) {
            //用来存放返回的键值对信息
            HashMap<String, Object> commentMap = new HashMap<>();

            CommentEntityImpl commentEntity = (CommentEntityImpl) comment;
            Date time = comment.getTime();
            String dateString = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, time);
            commentMap.put("orderTime", time);
            commentMap.put("time", dateString);
            commentMap.put("message", commentEntity.getMessage());
            result.add(commentMap);
        }


        if (historicProcessInstance != null && historicProcessInstance.getEndTime() != null) {
            HashMap<String, Object> commentMap = new HashMap<>();
            commentMap.put("message", "审批结束");
            Date endTime = historicProcessInstance.getEndTime();
            commentMap.put("orderTime", endTime);
            String endTimeString = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime);
            commentMap.put("time", endTimeString);
            result.add(commentMap);
        }

        //对查询所有审批信息根据时间进行排序
        result.sort((o1, o2) -> {
            Date time1 = (Date) o1.get("orderTime");
            Date time2 = (Date) o2.get("orderTime");
            return time2.compareTo(time1);
        });

        return result;
    }

    /**
     * 根据任务id获取任务实例
     *
     * @param taskId
     * @return
     */
    public Task getTaskByTaskId(String taskId) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        return task;
    }

    /**
     * 根据流程实例id获取任务实例
     *
     * @param processInstanceId
     * @return
     */
    public List<Task> getTaskByProInstId(String processInstanceId) {
        List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstanceId).orderByTaskCreateTime().desc().list();
        return tasks;
    }

    /**
     * 读取直接分配给当前人的任务
     *
     * @param taskAssignee
     * @return
     */
    public List<Task> getTasksByUserId(String taskAssignee) {
        return taskService.createTaskQuery().taskAssignee(taskAssignee).orderByTaskCreateTime().desc().list();
    }

    /**
     * 获取任务数量
     *
     * @param taskAssignee
     * @return
     */
    public long getTaskCount(String taskAssignee) {
        long count = taskService.createTaskQuery().taskAssignee(taskAssignee).count();
        return count;
    }

    /**
     * 设置变量
     *
     * @param taskId
     * @param variableName
     * @param value
     */
    public void setVariable(String taskId, String variableName, Object value) {
        taskService.setVariable(taskId, variableName, value);
    }

    /**
     * 根据流程定义key和任务处理人查找相关任务
     *
     * @param assignee
     * @param processDefinitionKey
     * @return
     */
    public List<Task> getTaskCandidateOrAssignedByKey(String assignee, String processDefinitionKey) {
        List<Task> tasks = taskService.createTaskQuery().taskCandidateOrAssigned(assignee)
                .processDefinitionKey(processDefinitionKey).list();
        return tasks;
    }


    /**
     * 获取流程变量
     *
     * @param taskId
     * @param variableName
     * @return
     */
    public Object getVariable(String taskId, String variableName) {
        return taskService.getVariable(taskId, variableName);
    }


    /**
     * 同意审批
     *
     * @param taskId
     * @param username
     */
    public void agreeProcess(String taskId, String username) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (!task.getAssignee().equals(username)) {
            throw new BaseException("审批人不符合");
        }
        Map<String, List<String>> nextTaskNameMap = nextTaskName(taskId, "同意");
        List<String> nextTaskNameList = nextTaskNameMap.get("nameList");
        List<String> defaultNameList = nextTaskNameMap.get("defaultNameList");
        //默认连线，直接同意
        if (defaultNameList != null && defaultNameList.size() == 1) {
            completeTask(taskId, username, "同意");
        }
        //同意连线
        if (nextTaskNameList != null && nextTaskNameList.size() == 1) {
            String executionId = taskService.createTaskQuery().taskId(taskId).singleResult().getExecutionId();
            try {
                revoke(executionId, username, "同意", "同意");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (nextTaskNameList != null && nextTaskNameList.size() > 1) {
            throw new RuntimeException("该流程图有问题，请联系管理员");
        }
    }

    /**
     * 驳回审批
     *
     * @param taskId
     * @param username
     * @param message
     */
    @Transactional
    public void disAgreeProcess(String taskId, String username, String message) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (!task.getAssignee().equals(username)) {
            throw new BaseException("审批人不符合");
        }
        Map<String, List<String>> nextTaskNameMap = nextTaskName(taskId, "驳回");
        List<String> nextTaskNameList = nextTaskNameMap.get("nameList");
        List<String> defaultNameList = nextTaskNameMap.get("defaultNameList");

        if (defaultNameList.size() > 0) {

            String startUserId = historyService.createHistoricProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult().getStartUserId();
            //该流程有一个出线，驳回则把该流程撤销
            taskService.addComment(taskId, task.getProcessInstanceId(), username + "驳回了" + startUserId + "的申请，理由：" + message);
            processRuntimeService.deleteProcessInstanceById(task.getProcessInstanceId(), username + "驳回了" + startUserId + "的申请，理由：" + message);

        }

        if (nextTaskNameList != null && nextTaskNameList.size() == 0) {
            //结束流程
            System.out.println("结束流程");

        }
        if (nextTaskNameList != null && nextTaskNameList.size() == 1) {
            String executionId = taskService.createTaskQuery().taskId(taskId).singleResult().getExecutionId();
            try {
                revoke(executionId, username, "驳回", message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (nextTaskNameList != null && nextTaskNameList.size() > 1) {
            throw new RuntimeException("该流程图有问题，请联系管理员");
        }
    }

    /**
     * 跳转到指定的节点
     * <p>
     * 1、获取当前任务所在的节点
     * 2、获取所在节点的流出方向
     * 3、记录所在节点的流出方向，并将所在节点的流出方向清空
     * 4、获取目标节点
     * 5、创建新的方向
     * 6、将新的方向set到所在节点的流出方向
     * 7、完成当前任务
     * 8、还原所在节点的流出方向
     *
     * @param executionId
     * @param username
     * @param flag        同意或驳回
     */
    public void revoke(String executionId, String username, String flag, String message) {

        Task task = taskService.createTaskQuery().executionId(executionId).singleResult();
        if (task == null) {
            throw new RuntimeException("流程未启动或已执行完成，无法撤回");
        }

        //LoginUser loginUser = SessionContext.getLoginUser();
        List<HistoricTaskInstance> htiList = historyService.createHistoricTaskInstanceQuery()
                .executionId(executionId)
                .orderByTaskCreateTime()
                .asc()
                .list();
        String myTaskId = null;
        HistoricTaskInstance myTask = null;
        for (HistoricTaskInstance hti : htiList) {
            //判断当前人是否是历史节点某一点的审批人
            if (username.equals(hti.getAssignee())) {
                //把历史任务实例中的任务赋值给我的任务，用于之后的跳转
                myTaskId = hti.getId();
                myTask = hti;
                break;
            }
        }
        if (null == myTaskId) {
            throw new BaseException("该任务非当前用户提交，无法撤回");
        }

        String processDefinitionId = myTask.getProcessDefinitionId();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);

        //变量
//		Map<String, VariableInstance> variables = runtimeService.getVariableInstances(currentTask.getExecutionId());
//        String myActivityId = null;
//        List<HistoricActivityInstance> haiList = historyService.createHistoricActivityInstanceQuery()
//                .executionId(myTask.getExecutionId()).finished().list();
//        for (HistoricActivityInstance hai : haiList) {
//            if (myTaskId.equals(hai.getTaskId())) {
//                myActivityId = hai.getActivityId();
//                break;
//            }
//        }
//        FlowNode myFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(myActivityId);


        Execution execution = runtimeService.createExecutionQuery().executionId(task.getExecutionId()).singleResult();
        String activityId = execution.getActivityId();
        //logger.warn("------->> activityId:" + activityId);
        //节点信息
        FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(activityId);

        //记录原活动方向
        List<SequenceFlow> oriSequenceFlows = new ArrayList<SequenceFlow>();
        oriSequenceFlows.addAll(flowNode.getOutgoingFlows());

        //清理活动方向
        flowNode.getOutgoingFlows().clear();

        //建立新方向
        List<SequenceFlow> newSequenceFlowList = new ArrayList<>();

        //同意或驳回流程
        for (SequenceFlow oriSequenceFlow : oriSequenceFlows) {
            if (flag.equals(oriSequenceFlow.getName())) {
                newSequenceFlowList.add(oriSequenceFlow);
            }
        }
        //建立新活动方向
        flowNode.setOutgoingFlows(newSequenceFlowList);


//        //根据同意与否建立新方向（驳回）
//        List<SequenceFlow> newSequenceFlowList = new ArrayList<SequenceFlow>();
//        SequenceFlow newSequenceFlow = new SequenceFlow();
//        newSequenceFlow.setId("newSequenceFlowId");
//        newSequenceFlow.setSourceFlowElement(flowNode);
//        newSequenceFlow.setTargetFlowElement(myFlowNode);
//        newSequenceFlowList.add(newSequenceFlow);
//        flowNode.setOutgoingFlows(newSequenceFlowList);
//
        Authentication.setAuthenticatedUserId(username);
        //添加评论
        //获取该请求的申请者
//        String startUserId = historyService.createHistoricProcessInstanceQuery().processDefinitionId(processDefinitionId).singleResult().getStartUserId();
        String startUserId = historyService.createHistoricProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult().getStartUserId();
        if (message.equals("同意")) {
            taskService.addComment(task.getId(), task.getProcessInstanceId(), username + message + "了" + startUserId + "的申请");
        } else {
            taskService.addComment(task.getId(), task.getProcessInstanceId(), username + "驳回了" + startUserId + "的申请，理由：" + message);
        }


        Map<String, Object> currentVariables = new HashMap<>();
        currentVariables.put("applier", username);
        //完成任务
        taskService.complete(task.getId(), currentVariables);
        //恢复原方向
        flowNode.setOutgoingFlows(oriSequenceFlows);
    }


    /**
     * 获取下一节点信息
     *
     * @param taskId
     * @param flag   同意或驳回
     * @return
     */
    public Map<String, List<String>> nextTaskName(String taskId, String flag) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        //返回下一节点信息
        Map<String, List<String>> nextTaskNameMap = new HashMap<>();
        //默认连线名称
        List<String> defaultNameList = new ArrayList<>();
        List<String> nameList = new ArrayList<>();
        HashMap<String, Object> vars = new HashMap<>();
        vars.put("message", flag);
        //根据流程定义id获取bpmnModel对象
        BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
        //获取当前节点信息
        FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(task.getTaskDefinitionKey());
        //获取当前节点输出连线
        List<SequenceFlow> outgoingFlows = flowNode.getOutgoingFlows();
        //遍历输出连线
        for (SequenceFlow outgoingFlow : outgoingFlows) {
            //获取输出节点元素
            FlowElement targetFlowElement = outgoingFlow.getTargetFlowElement();
            //判断输出节点的连线名称
            if (outgoingFlow.getName() == null || outgoingFlow.getName() == "") {
                //判断空节点有几个
                defaultNameList.add(outgoingFlow.getTargetFlowElement().getName());

            }

            System.out.println("----------------------------------------------------------");
            System.out.println("下一节点的名称：" + outgoingFlow.getTargetFlowElement().getName());
            //下一节点的id
            System.out.println("下一节点的id：" + outgoingFlow.getTargetFlowElement().getId());
            System.out.println("下一节点的连线名称： " + outgoingFlow.getName());
            System.out.println("下一节点的的id： " + outgoingFlow.getTargetRef());
            System.out.println("该节点的顺序流（连线）id ： " + outgoingFlow.getId());


            if (flag.equals(outgoingFlow.getName())) {
                nameList.add(outgoingFlow.getTargetFlowElement().getName());
            }

        }
        nextTaskNameMap.put("defaultNameList", defaultNameList);
        nextTaskNameMap.put("nameList", nameList);

        return nextTaskNameMap;
    }

    /**
     * el表达式判断
     *
     * @param expression
     * @param vars
     * @return
     */
    private boolean isCondition(String expression, Map<String, Object> vars) {
        if (expression == null || expression == "") {
            return true;
        }

        //分割表达式
        String[] exprArr = expression.split("[{}$&]");
        for (String expr : exprArr) {
            //是否包含键message
            if (expr.contains("message")) {
                if (!vars.containsKey("message")) {
                    continue;
                }
                if (expr.contains("==")) {
                    String[] primes = expr.split("==");
                    String valExpr = primes[1].trim();
                    if (valExpr.startsWith("'")) {
                        valExpr = valExpr.substring(1);
                    }
                    if (valExpr.endsWith("'")) {
                        valExpr = valExpr.substring(0, valExpr.length() - 1);
                    }
                    if (primes.length == 2 && valExpr.equals(vars.get("message"))) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 驳回到指定节点（参考用）勿删
     *
     * @param
     * @param taskId
     * @param map
     * @return
     */
    public boolean runNodes(String taskId, String username, Map<String, Object> map) {
        String myTaskId = null;
        //判断当前用户是否为该节点处理人
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (username.equals(task.getAssignee())) {
            myTaskId = task.getId();
        }
        //如果当前节点处理人不是该用户,就无法进行驳回操作
        if (null == myTaskId) {
            System.out.println("当前用户无法驳回");
        }
        //获取当前节点
        String currActivityId = task.getTaskDefinitionKey();
        String processDefinitionId = task.getProcessDefinitionId();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        FlowNode currFlow = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currActivityId);

        if (null == currFlow) {
            List<SubProcess> subProcessList = bpmnModel.getMainProcess().findFlowElementsOfType(SubProcess.class, true);
            for (SubProcess subProcess : subProcessList) {
                FlowElement flowElement = subProcess.getFlowElement(currActivityId);
                if (flowElement != null) {
                    currFlow = (FlowNode) flowElement;
                    break;
                }
            }
        }
        //获取目标节点
        FlowNode targetFlow = (FlowNode) bpmnModel.getFlowElement("目标id");

        //如果不是同一个流程(子流程)不能驳回
        if (!(currFlow.getParentContainer().equals(targetFlow.getParentContainer()))) {
            throw new RuntimeException("此处无法进行驳回操作");
        }

        //记录原活动方向
        List<SequenceFlow> oriSequenceFlows = Lists.newArrayList();
        oriSequenceFlows.addAll(currFlow.getOutgoingFlows());

        //清理活动方向
        currFlow.getOutgoingFlows().clear();

        //建立新的方向
        List<SequenceFlow> newSequenceFlows = Lists.newArrayList();
        SequenceFlow newSequenceFlow = new SequenceFlow();
        String uuid = UUID.randomUUID().toString().replace("-", "");
        newSequenceFlow.setId(uuid);
        newSequenceFlow.setSourceFlowElement(currFlow);  //原节点
        newSequenceFlow.setTargetFlowElement(targetFlow);  //目标节点
        newSequenceFlows.add(newSequenceFlow);
        currFlow.setOutgoingFlows(newSequenceFlows);

        //审批意见叠加
        Map<String, Object> variables = task.getProcessVariables();
        //拒绝,通过,驳回 驳回指定节点
        //List<ApprovalOpinionDTO> approvalOpinionDTOs = new ArrayList<>();
        //获取工作流审批记录
//        Object options = variables.get(Constant.ACT_APPLY_OPINION_LIST);
//        if (null != options) {
//            approvalOpinionDTOs = JSONObject.parseArray(options.toString(), ApprovalOpinionDTO.class);
//        }
        //添加审批过后的返回提示信息
//        ApprovalOpinionDTO applyOpinionDTO = ApprovalOpinionConverter.INSTANCE.vo2dto(approvalOpinionVO);
//        applyOpinionDTO.setFlagStr(applyOpinionDTO.getTaskNodeName()+"撤回到"+targetFlow.getName());
//        approvalOpinionDTOs.add(applyOpinionDTO);
//        map.put(Constant.ACT_APPLY_OPINION_LIST, JSONObject.toJSONString(approvalOpinionDTOs));

        //完成节点任务
        taskService.complete(task.getId(), map);
        //恢复原方向
        currFlow.setOutgoingFlows(oriSequenceFlows);
        return true;
    }


    /**
     * 分页读取直接分配给当前人的任务
     * 未处理流程
     *
     * @param assignee
     * @return
     */
    public Page<List<Map<String, String>>> getUserTasks(BasePageQuery pageQuery, String assignee) {
        TaskQuery taskQuery = taskService.createTaskQuery();
        List<Task> taskList = taskQuery.taskAssignee(assignee).orderByTaskCreateTime().asc().listPage((pageQuery.getPageNum() - 1) * pageQuery.getPageSize(), pageQuery.getPageSize());
        Page<List<Map<String, String>>> list = new Page<>();
        list.setTotal(taskQuery.count());
        list.setPageNum(pageQuery.getPageNum());
        list.setPageSize(pageQuery.getPageSize());

        //为解决懒加载的问题，把实体类转换为map
        //用于返回给前端的任务集合
        List<Map<String, String>> userTaskList = new ArrayList<>();
        for (Task userTask : taskList) {
            Map<String, String> userTaskMap = new HashMap<>();
            userTaskMap.put("taskId", userTask.getId());
            //流程名称
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(userTask.getProcessDefinitionId()).singleResult();
            Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(processDefinition.getDeploymentId()).singleResult();
            userTaskMap.put("processName", deployment.getName());
            userTaskMap.put("name", userTask.getName());
            userTaskMap.put("Assignee", userTask.getAssignee());
            //所属模块

            Model model = repositoryService.createModelQuery().deploymentId(processDefinition.getDeploymentId()).singleResult();
            String metaInfo = model.getMetaInfo();
            Map<String, String> metaInfoMap = JSON.parseObject(metaInfo, Map.class);
            String module = metaInfoMap.get("module");
            userTaskMap.put("module", module);
            //获取流程描述
            String description = metaInfoMap.get("description");
            userTaskMap.put("description", description);

            //获取processInstanceId
            userTaskMap.put("processInstanceId", userTask.getProcessInstanceId());


            //获取流程申请人
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(userTask.getProcessInstanceId()).singleResult();
            userTaskMap.put("startUserId", historicProcessInstance.getStartUserId());

            //流程发起时间
            userTaskMap.put("startDate", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, historicProcessInstance.getStartTime()));


            userTaskList.add(userTaskMap);
        }
        list.add(userTaskList);
        return list;
    }

    /**
     * 我的流程
     *
     * @param organizerName 对应数据库act_hi_procinst中START_USER_ID_
     */
    public Page<List<Map<String, String>>> findMyProcess(String organizerName, BasePageQuery pageQuery) {
        HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery();
        List<HistoricProcessInstance> historicProcessInstancesList = historicProcessInstanceQuery.startedBy(organizerName).listPage((pageQuery.getPageNum() - 1) * pageQuery.getPageSize(), pageQuery.getPageSize());
        Page<List<Map<String, String>>> list = new Page<>();
        list.setTotal(historicProcessInstanceQuery.count());
        list.setPageNum(pageQuery.getPageNum());
        list.setPageSize(pageQuery.getPageSize());

        //System.out.println(historicProcessInstancesList);
        //为解决懒加载的问题，把实体类转换为map
        //用于返回给前端的任务集合
        List<Map<String, String>> myHistoryProcessInstanceList = new ArrayList<>();
        for (HistoricProcessInstance myHistoryProcessInstance : historicProcessInstancesList) {
            Map<String, String> myHistoryProcessInstanceMap = new HashMap<>();
            //获取流程名称
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(myHistoryProcessInstance.getProcessDefinitionId()).singleResult();
            Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(processDefinition.getDeploymentId()).singleResult();
            myHistoryProcessInstanceMap.put("processName", deployment.getName());

            myHistoryProcessInstanceMap.put("processInstanceId", myHistoryProcessInstance.getId());

            //获取所属模块
            Model model = repositoryService.createModelQuery().deploymentId(processDefinition.getDeploymentId()).singleResult();
            if (model == null) {
                System.out.println("没有模型数据");
                throw new BaseException("后台有错，请联系管理员");

            }
            Map<String, String> metaInfoMap = JSON.parseObject(model.getMetaInfo(), Map.class);
            myHistoryProcessInstanceMap.put("module", metaInfoMap.get("module"));

            //获取当前节点(未开始 我觉得 不应该存在)
            Task task = taskService.createTaskQuery().processInstanceId(myHistoryProcessInstance.getId()).singleResult();
            if (task == null) {
                myHistoryProcessInstanceMap.put("taskName", "结束");
            } else {
                myHistoryProcessInstanceMap.put("taskName", "任务节点");
                //myHistoryProcessInstanceMap.put("taskName", task.getName()+"任务节点");
            }

            //获取processDefinitionId
            myHistoryProcessInstanceMap.put("processDefinitionId", processDefinition.getId());


            //获取流程描述
            String description = metaInfoMap.get("description");
            myHistoryProcessInstanceMap.put("description", description);
            //获取流程状态
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                    .processInstanceId(myHistoryProcessInstance.getId())
                    .singleResult();
            //三种状态审批中，已完成，（已暂停）
            if (processInstance != null) {
                myHistoryProcessInstanceMap.put("processStatus", "审批中");
            } else {
                myHistoryProcessInstanceMap.put("processStatus", "已完成");
            }

            // myHistoryProcessInstanceMap.put("Assignee", myHistoryProcessInstance);
            myHistoryProcessInstanceList.add(myHistoryProcessInstanceMap);
        }
        list.add(myHistoryProcessInstanceList);
        return list;
    }


    /**
     * 已处理流程
     *
     * @param username
     * @param pageQuery
     * @return
     */
    public Page<List<Map<String, String>>> findMyHisProcess(String username, BasePageQuery pageQuery) {
        HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery();
        List<HistoricTaskInstance> historicTaskInstances = historicTaskInstanceQuery.taskAssignee(username).listPage((pageQuery.getPageNum() - 1) * pageQuery.getPageSize(), pageQuery.getPageSize());
        Page<List<Map<String, String>>> list = new Page<>();
        list.setTotal(historicTaskInstanceQuery.count());
        list.setPageNum(pageQuery.getPageNum());
        list.setPageSize(pageQuery.getPageSize());
        //为解决懒加载的问题，把实体类转换为map
        //用于返回给前端的任务集合
        List<Map<String, String>> historicTaskList = new ArrayList<>();
        for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
            //判断历史任务的实例中是否有结束时间，如果没有则为要处理的时间
            Date endTime = historicTaskInstance.getEndTime();


            if (endTime != null) {
                Map<String, String> historicTaskMap = new HashMap<>();
                historicTaskMap.put("taskId", historicTaskInstance.getId());
                //获取流程名称
                ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(historicTaskInstance.getProcessDefinitionId()).singleResult();
                Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(processDefinition.getDeploymentId()).singleResult();
                historicTaskMap.put("processName", deployment.getName());
                historicTaskMap.put("name", historicTaskInstance.getName());
                historicTaskMap.put("Assignee", historicTaskInstance.getAssignee());
                //所属模块

                Model model = repositoryService.createModelQuery().deploymentId(processDefinition.getDeploymentId()).singleResult();
                if (model==null){
                    throw new RuntimeException("模型为空+部署id"+processDefinition.getDeploymentId());
                }
                String metaInfo = model.getMetaInfo();
                Map<String, String> metaInfoMap = JSON.parseObject(metaInfo, Map.class);
                String module = metaInfoMap.get("module");
                historicTaskMap.put("module", module);
                //获取流程描述
                String description = metaInfoMap.get("description");
                historicTaskMap.put("description", description);

                //获取当前节点
                //获取当前节点(未开始 我觉得 不应该存在)
                Task task = taskService.createTaskQuery().processInstanceId(historicTaskInstance.getProcessInstanceId()).singleResult();
                if (task == null) {
                    historicTaskMap.put("taskName", "结束");
                } else {
                    historicTaskMap.put("taskName", "任务节点");
                    //myHistoryProcessInstanceMap.put("taskName", task.getName()+"任务节点");
                }

                //获取流程状态
                ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                        .processInstanceId(historicTaskInstance.getId())
                        .singleResult();
                //三种状态审批中，已完成，（已暂停）
                if (processInstance != null) {
                    historicTaskMap.put("processStatus", "审批中");
                } else {
                    historicTaskMap.put("processStatus", "已完成");
                }

                historicTaskList.add(historicTaskMap);
            }
        }
        list.add(historicTaskList);
        return list;
    }

    /**
     * Purpose：创建文件类型的附件
     *
     * @param attachmentType        文件类型
     * @param taskId                任务id
     * @param processInstanceId     流程id
     * @param attachmentName        文件名称
     * @param attachmentDescription 文件描述
     * @param content               文件内容
     * @return Attachment
     */
    public Attachment createAttachment(String attachmentType, String taskId, String processInstanceId,
                                       String attachmentName, String attachmentDescription, InputStream content) {
        return taskService.createAttachment(attachmentType, taskId, processInstanceId, attachmentName,
                attachmentDescription, content);
    }

    /**
     * Purpose：创建文件类型的附件
     *
     * @param attachmentType        文件类型
     * @param taskId                任务id
     * @param processInstanceId     流程id
     * @param attachmentName        文件名称
     * @param attachmentDescription 文件描述
     * @param url                   文件地址
     * @return Attachment
     */
    public Attachment createAttachment(String attachmentType, String taskId, String processInstanceId,
                                       String attachmentName, String attachmentDescription, String url) {
        /**
         * String attachmentType,
         * String taskId,
         * String processInstanceId,
         * String attachmentName,
         * String attachmentDescription,
         * String url
         */
        return taskService.createAttachment(attachmentType, taskId, processInstanceId, attachmentName, attachmentDescription, url);
    }

    /**
     * Purpose：修改后保存文件
     *
     * @param attachment
     */
    public void saveAttachment(Attachment attachment) {
        taskService.saveAttachment(attachment);
    }

    /**
     * 删除附件
     *
     * @param attachmentId
     */
    public void deleteAttachment(String attachmentId) {
        taskService.deleteAttachment(attachmentId);
    }

    /**
     * 根据任务id获取相应附件信息
     *
     * @param taskId
     * @return
     */
    public List<Attachment> getTaskAttachments(String taskId) {
        return taskService.getTaskAttachments(taskId);
    }

    /**
     * 根据附件id获取附件信息
     *
     * @param attachmentId
     * @return
     */
    public Attachment getAttachment(String attachmentId) {
        return taskService.getAttachment(attachmentId);
    }

    /**
     * 根据附件id获取附件内容
     *
     * @param attachmentId
     * @return
     */
    public InputStream getAttachmentContent(String attachmentId) {
        return taskService.getAttachmentContent(attachmentId);
    }

    /**
     * 根据流程定义id获取相关附件信息列表
     *
     * @param processInstanceId
     * @return
     */
    public List<Attachment> getAttachmentByProcessInstanceId(String processInstanceId) {
        return taskService.getProcessInstanceAttachments(processInstanceId);
    }

    /**
     * 删除当前任务相关附件
     *
     * @param taskId
     */
    public void deleteTaskAttachment(String taskId) {
        List<Attachment> attachments = taskService.getTaskAttachments(taskId);
        if (attachments != null) {
            for (Attachment attachment : attachments) {
                taskService.deleteAttachment(attachment.getId());
            }
        }
    }


}